﻿using System;
using System.Linq;
using com.yoozoo.gta.Extension.UGUI.ScreenOrientationEx;
using UnityEditor.Compilation;
using UnityEditor.SceneManagement;
using UnityEngine.SceneManagement;
using Yoozoo.UI;

namespace com.yoozoo.gta.Extension.UGUI.Editor
{
#if UNITY_EDITOR
    using UnityEditor;
    using UnityEngine;

    [InitializeOnLoad]
    public class ResolutionMonitor
    {
        private static Vector2Int lastResolution;
        private static int waitRefreshFrameCount;
        
        private const string UIRootPath = "Assets/ResourcesAssets/Prefabs/UI";
        private const string ResourceUIRootPath = "Assets/ResourcesAssets/Prefabs/UI";
        
        [Obsolete("Obsolete")]
        static ResolutionMonitor()
        {
            //用来监听GameView的分辨率变化
            EditorApplication.update += UpdateResolution;  
            EditorApplication.playModeStateChanged
                += (state) =>
                {
                    
                    Debug.Log("【PlayModeStateChange】=======》 " + Enum.GetName(typeof(PlayModeStateChange),state));
                    var editorChangePlayMode =
                        state == PlayModeStateChange.ExitingEditMode || state == PlayModeStateChange.ExitingPlayMode;
                    ScreenOrientManager.GetInstance().EditorChangePlayMode = editorChangePlayMode;

                    //当编辑器退出play后，刷新一下
                    if (state == PlayModeStateChange.EnteredEditMode)
                    {
                        waitRefreshFrameCount = 30;
                        var detector = GameObject.FindObjectOfType<ScreenOrientDetector>();
                        if (detector)
                        {
                            detector.ForceCleanup(); 
                            detector.Refresh();
                        }
                    }
                };
            
            EditorSceneManager.sceneSaving += OnFileMenuSaving;
            EditorSceneManager.sceneSaved += OnFileMenuSaved;
            
            lastResolution = GetGameViewSize();

            //用来监听prefab的保存
            PrefabStage.prefabStageOpened += PrefabStageOpened;
            PrefabStage.prefabSaving += PrefabSaving;
            PrefabStage.prefabSaved += PrefabSaved;
            PrefabStage.prefabStageClosing += PrefabStageClosing;
            PrefabStage.prefabStageDirtied += PrefabStageDirtied;
            
            
            CompilationPipeline.compilationStarted += CompilationPipelineOnCompilationStarted;
            CompilationPipeline.compilationFinished += CompilationPipelineOnCompilationFinished;
            CompilationPipeline.assemblyCompilationStarted += CompilationPipelineOnAssemblyCompilationStarted;
            CompilationPipeline.assemblyCompilationFinished += CompilationPipelineOnAssemblyCompilationFinished;
        }

        private static void CompilationPipelineOnAssemblyCompilationFinished(string arg1, CompilerMessage[] arg2)
        {
            UnityEngine.Debug.LogFormat("CompilationPipelineOnAssemblyCompilationFinished {0}   ", arg1);  
        }

        private static void CompilationPipelineOnAssemblyCompilationStarted(string obj)
        {  
            UnityEngine.Debug.LogFormat("CompilationPipelineOnAssemblyCompilationStarted {0}   ", obj);
        }

        private static void CompilationPipelineOnCompilationFinished(object obj)   
        {
            if(Application.isPlaying)   return;
            UnityEngine.Debug.Log("CompilationPipelineOnCompilationFinished " + obj);

            waitRefreshFrameCount = 10;  
        }

        private static void CompilationPipelineOnCompilationStarted(object obj)
        {
            var gameViewSize = GetGameViewSize();
            UnityEngine.Debug.Log("CompilationPipelineOnCompilationStarted " + gameViewSize);

        }

        private static void OnFileMenuSaving(Scene scene, string path)
        {
            Debug.Log("OnFileMenuSaving: " + scene.name);
        }

        private static void OnFileMenuSaved(Scene scene)
        {
            if (Application.isPlaying) return;
            //获取obj的prefab路径，并判断是否在UIRootPath下
            Debug.Log("OnFileMenuSaved: " + scene.name);
        }


        private static void PrefabStageDirtied(PrefabStage obj)
        {
            if (Application.isPlaying) return;
            //获取obj的prefab路径，并判断是否在UIRootPath下
            var currentPrefabStage = PrefabStageUtility.GetCurrentPrefabStage();
            if (currentPrefabStage.assetPath.Contains(UIRootPath) || currentPrefabStage.assetPath.Contains(ResourceUIRootPath))
            {
                Debug.Log("PrefabStageDirtied: " + obj.assetPath);
            }
        }


        private static void PrefabSaved(GameObject obj)
        {
            if (Application.isPlaying) return;
            //获取obj的prefab路径，并判断是否在UIRootPath下
            var currentPrefabStage = PrefabStageUtility.GetCurrentPrefabStage();
            if (currentPrefabStage.assetPath.Contains(UIRootPath) || currentPrefabStage.assetPath.Contains(ResourceUIRootPath))
            {
                Debug.Log("PrefabSaved: " + obj.name);
            }
        }

        private static void PrefabSaving(GameObject obj)  
        {
            if (Application.isPlaying) return;
            //fix 有时保存时,横竖屏判断不对
            ScreenOrientManager.GetInstance().JustRefreshOrientation();
            
            //获取obj的prefab路径，并判断是否在UIRootPath下
            var currentPrefabStage = PrefabStageUtility.GetCurrentPrefabStage();
            if (currentPrefabStage.assetPath.Contains(UIRootPath) || currentPrefabStage.assetPath.Contains(ResourceUIRootPath))
            {
                Debug.Log("PrefabSaving: " + obj.name);
                var soItem = obj.GetComponent<ScreenOrientItem>();
                
                if(soItem != null && soItem.SaveConfigData())
                {
                    Debug.Log("=======PrefabSaving: " + obj.name + "   Save");
                    PrefabUtility.SaveAsPrefabAsset(obj, currentPrefabStage.assetPath);
                }
                else
                {
                    EditorUtility.DisplayDialog("Error", "Failed to save config data. Please check.", "OK");
                }
            }
        }

        private static void PrefabStageOpened(PrefabStage obj)
        {
            if(Application.isPlaying)   return;
            
            var detector = obj.prefabContentsRoot.GetComponentInParent<ScreenOrientDetector>();
            if (detector)
            {  
                detector.Refresh();
            }
            if (obj.assetPath.Contains(UIRootPath) || obj.assetPath.Contains(ResourceUIRootPath))
            {
                
                
                if (ScreenOrientManager.GetInstance().AutoAdd)
                {
                    try
                    {
                        var soItem = obj.prefabContentsRoot.GetOrAddComponent<ScreenOrientItem>();
                        Debug.Log("PrefabStageOpened: " + obj.assetPath);
                        soItem.CleanUpAdapter();
                        soItem.InitAllAdapter();
                        soItem.RegisterAllListener(true); //注册监听就会触发执行
                    }
                    catch (Exception e)
                    {
                        Debug.LogError("PrefabStageOpened: 报错，请解决报错后再编辑！！！！！！！！！！" + obj.assetPath);
                        Debug.LogError(e);
                    }
                  
                    
                }
                
            }
        }

        private static void PrefabStageClosing(PrefabStage obj)
        {

            if (ScreenOrientManager.GetInstance().EditorChangePlayMode || Application.isPlaying)
            {
                return;
            }
            if (obj.assetPath.Contains(UIRootPath) || obj.assetPath.Contains(ResourceUIRootPath))
            {  
                var item = obj.prefabContentsRoot.GetComponent<ScreenOrientItem>();
                if (ScreenOrientManager.GetInstance().AutoRemove)
                {
                    UnityEngine.Debug.LogFormat("PrefabStageClosing: {0}", obj.assetPath);

                    if (item)
                    {
                        var root = obj.prefabContentsRoot;
                        item.CleanUpAdapter();
                        if (item.ChangeHandlersList.Count == 0)
                        {
                            GameObject.DestroyImmediate(item);
                        }
                        else
                        {
                            item.ResetToLandscape();
                        }
                        //Save 会导致卡顿，先不管，导入时会执行一次删除操作
                        UnityEngine.Debug.LogFormat("=======PrefabStageClosing: {0}   Save", obj.assetPath);
                        PrefabUtility.SaveAsPrefabAsset(root, obj.assetPath);
                    }
                }
                else
                {
                    if (item)
                    {
                        item.UnRegisterAllListener();
                        PrefabUtility.SaveAsPrefabAsset(obj.prefabContentsRoot, obj.assetPath);
                    }
                    PrefabUtility.SaveAsPrefabAsset(obj.prefabContentsRoot, obj.assetPath);
                }
            }
            
            waitRefreshFrameCount = 3;
        }

        private static void refreshDetector()
        {
            var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
            if(prefabStage != null)
            {
                var detector = prefabStage.prefabContentsRoot.GetComponentInParent<ScreenOrientDetector>();
                if(detector)
                {
                    detector.Refresh();
                }
                else
                {
                    ScreenOrientManager.GetInstance().UpdateOrientionByGameView();
                }
            }
            else
            {
                var detector = GameObject.FindObjectOfType<ScreenOrientDetector>();
                if (detector)
                {
                    detector.Refresh();
                }
            }
        }
        private static void UpdateResolution()
        {
            if(Application.isPlaying) return;
            Vector2Int currentResolution = GetGameViewSize(); 
            var currentScreenOrientation = getOrientation(currentResolution);
            if (currentResolution != lastResolution || currentScreenOrientation != ScreenOrientManager.GetInstance().CurrentLogicOrientation)
            {
                Debug.Log("Game view resolution changed: " + currentResolution);
                lastResolution = currentResolution;

                refreshDetector();

            }

            if (waitRefreshFrameCount > 0)
            {
                waitRefreshFrameCount--;
                if (waitRefreshFrameCount == 0 )  
                {
                    refreshDetector();
                }
            }
        }

        private static ScreenOrientation getOrientation(Vector2Int currentResolution)
        {
            if (currentResolution.x > currentResolution.y)
            {
                return UnityEngine.ScreenOrientation.LandscapeLeft;
            }
            else
            {
                return UnityEngine.ScreenOrientation.Portrait;
            }
        }

        public static Vector2Int GetGameViewSize()
        {
            var mouseOverWindow = UnityEditor.EditorWindow.mouseOverWindow;
            System.Reflection.Assembly assembly = typeof(UnityEditor.EditorWindow).Assembly;
            System.Type type = assembly.GetType("UnityEditor.PlayModeView");

            Vector2 size = (Vector2)type.GetMethod(
                "GetMainPlayModeViewTargetSize",
                System.Reflection.BindingFlags.NonPublic |
                System.Reflection.BindingFlags.Static
            ).Invoke(mouseOverWindow, null);

            return new Vector2Int((int)size.x, (int)size.y);
        }



    }
#endif
}